package bl.tools;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import ml.options.OptionSet;
import ml.options.Options;

public class ClassRunner {
	
	private static final int maxPartSize = 40;
	
	private static String pr, dir;
	
	private ArrayList<String> partitionList = new ArrayList<String>();
	
	ClassRunner(ArrayList<String> partitionList){
		if(partitionList.size() == 0){ // default packages to split
			this.partitionList.add("org.mozilla.javascript");
		} else
			this.partitionList = partitionList;
	}
	
	/**
	 * @param args
	 * @throws IOException 
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws IOException, InterruptedException {
		Options opt = new Options(args);
		opt.addSet("foo", 0, 10).addOption("pr", 
				Options.Separator.BLANK, Options.Multiplicity.ZERO_OR_ONE).addOption("dir",
				Options.Separator.BLANK, Options.Multiplicity.ONCE);
		
		OptionSet set = opt.getMatchingSet(false, false);
		
		if (set == null) {
			System.out.println("Usage:\n---------------------\n" +
					"\t-pr \t PackageRanking\n"+
					"\t-dir \t working directory\n");
			System.out.println("\nThe options library says:\n" + opt.getCheckErrors());
			System.exit(1);
		}
		pr = set.getOption("pr").getResultValue(0);
		dir = set.getOption("dir").getResultValue(0);
		
		ClassRunner mr = new ClassRunner(set.getData());
		mr.exec();
	}
	
	void exec() throws IOException, InterruptedException{
		System.out.println("Read in class ranking...");
		ArrayList<String> packages;
		packages = ranking2List(pr);
		System.out.println("Run the ranking...");
		runRanking(packages, dir);
		System.out.println("Writing output...");
		makeLists(dir);
	}
	
	ArrayList<String> ranking2List(String csv) throws IOException{
		ArrayList<String> out = new ArrayList<String>();
		FileReader fr = new FileReader(csv);
		BufferedReader br = new BufferedReader(fr);
		String line;
		while( (line = br.readLine()) != null ){
			if(line.equals("Entropy Score")){
				br.readLine();
				while( ! (line = br.readLine()).equals("") ){
					out.add(line.split("      ")[1]);
				}
			}
		}
		br.close();
		return out;
	}
	
	void runRanking(ArrayList<String> packages, String dir) throws IOException, InterruptedException{
		int i = 0;
		for( String p : packages ){
				String cmd = "--mine " +
				  "-class " + 
				  "-i " + dir + "\\data" + " " +
				  "-reincludeDummies " +
				  "-skipSelfEdges " +
				  "-reincludeJre " +
				  "-closeGraph " +
				  "-wof=_0 ";
				if( ! partitionList.contains(p)){
					cmd += "-suffix=_" + i + " " + p;
					System.out.println(cmd);
					bl.Main.main(cmd.split("\\s"));
				} else {
					String list = "\\list_classes_" + i;
					LOCCParser lp = new LOCCParser(dir + "\\size.txt");
					lp.writeClasses(dir + list, p, maxPartSize);
					for(int j = 0; j < lp.getNoPartitions(); j++){
						String cmd_x = cmd;
						cmd_x += "-suffix=_" + i + "-" + j + " -list=" + list + "_" + j + ".lst" + " " + p ;
						bl.Main.main(cmd_x.split("\\s"));
					}
				}
				i++;
		}
	}
	
	void makeLists(String dir) throws IOException{
		File[] files = new File(dir).listFiles();
		String cmd = "-o ranking_class_partAbsALL.csv " +
		  			 "-folder " + dir + " " +
		  			 "-i size.txt ";
		for(File f : files){
			if(f.getCanonicalPath().matches(".*class.*Scoring.*")){
				cmd += f.getName() + " ";
			}
		}
		Lists2CSV.main(cmd.split("\\s"));
	}

}
